use uuid::Uuid;
use wasm_bindgen::prelude::*;

use crate::wire::Wire;

#[wasm_bindgen]
#[derive(Debug, Clone, Copy)]
pub enum DeviceKind {
    /** 变压器 */
    TRANSFORMER = "TRANSFORMER",
    /** 母线 */
    BUSBAR = "BUSBAR",
}

#[wasm_bindgen]
#[derive(Debug)]
pub struct Device {
    id: String,
    kind: DeviceKind,
    name: Option<String>,
    power_source: bool,
    wires: Vec<Wire>,
}

#[wasm_bindgen]
impl Device {
    #[wasm_bindgen(constructor)]
    pub fn new(kind: DeviceKind) -> Device {
        Device {
            id: Uuid::new_v4().to_string(),
            kind,
            name: None,
            power_source: false,
            wires: vec![],
        }
    }

    #[wasm_bindgen(js_name = getId)]
    pub fn get_id(&self) -> String {
        self.id.clone()
    }

    #[wasm_bindgen(js_name = getKind)]
    pub fn get_kind(&self) -> DeviceKind {
        self.kind.clone()
    }

    #[wasm_bindgen(js_name = setName)]
    pub fn set_name(&mut self, value: String, f: &js_sys::Function) {
        let _ = f.call1(&JsValue::null(), &JsValue::from_str(&value));
        self.name = Some(value);
    }

    #[wasm_bindgen(js_name = getName)]
    pub fn get_name(&self) -> Option<String> {
        self.name.clone()
    }

    #[wasm_bindgen(js_name = setPowerSource)]
    pub fn set_power_source(&mut self, value: bool) {
        self.power_source = value;
    }

    #[wasm_bindgen(js_name = getPowerSource)]
    pub fn get_power_source(&self) -> bool {
        self.power_source
    }

    #[wasm_bindgen(js_name = addWire)]
    pub fn add_wire(&mut self, wire: Wire) {
        self.wires.push(wire);
    }

    #[wasm_bindgen(js_name = getWires)]
    pub fn get_wires(&self) -> Vec<Wire> {
        self.wires.clone()
    }
}
